package org.voidness.squaretilesframework.server;

import java.util.Map;

import org.voidness.oje2d.Vector2D;

/** Represents a character in the world server */
public class ServerActor {
    /** The network client associated with the actor */
    // private AbstractClient client = null;
    /** A reference to the map where the actor is */
    private ServerMap map = null;

    /** The name of the world the actor is in */
    private String worldName = null;

    /** The actor's name */
    private String name = null;

    /** The actor's location in the map */
    private int tileX;

    /** The actor's location in the map */
    private int tileY;

    /**
     * Default constructor
     * 
     * @param mClient The reference to the actor's network client
     * @param mMap The map where the actor is
     * @param mWorldName The name of the world the actor is in
     */
    public ServerActor(/* AbstractClient mClient, */ServerMap mMap,
            String mWorldName) {
        // client = mClient;
        map = mMap;
        worldName = mWorldName;
    }

    /**
     * Returns the actor's name
     * 
     * @return A string with the actor's name
     */
    public String getName() {
        return name;
    }

    /**
     * Returns the actor's associated network client
     * 
     * @return The actor's AbstractClient
     */
    /*
     * public AbstractClient getClient() { return client; }
     */

    /**
     * Returns the actor's world name
     * 
     * @return A string with the name of the world the actor is in
     */
    public String getWorldName() {
        return worldName;
    }

    /**
     * Returns the map the actor is in
     * 
     * @return The ServerMap the actor is in
     */
    public ServerMap getMap() {
        return map;
    }

    /**
     * (Re)defines the actor's name
     * 
     * @param mCharacterName The name to set
     */
    public void setName(String mCharacterName) {
        this.name = mCharacterName;
    }

    /**
     * Initializes the actor's data from an hashtable
     * 
     * @param mData The data to use
     */
    public void initFromHash(Map<String, String> mData) {
        int xPos = Integer.parseInt((String) mData.get("tileX"));
        int yPos = Integer.parseInt((String) mData.get("tileY"));

        synchronized (map) {
            System.out.println("Requested location for " + this.getName()
                    + " is " + xPos + "," + yPos);
            Vector2D validLocation =
                    map.getNearestValidLocation(new Vector2D(xPos, yPos));
            System.out.println("Valid location for " + this.getName() + " is "
                    + validLocation.getX() + "," + validLocation.getY());
            tileX = validLocation.getX();
            tileY = validLocation.getY();
            map.tileAt(tileX, tileY).setOccupier(this);
        }
    }

    /**
     * Returns the actor's position
     * 
     * @return The position's X component
     */
    public int getTileX() {
        return tileX;
    }

    /**
     * (Re)defines the actor's position
     * 
     * @param tileX The X position to set
     */
    public void setTileX(int tileX) {
        this.tileX = tileX;
    }

    /**
     * Returns the actor's position
     * 
     * @return The position's Y component
     */
    public int getTileY() {
        return tileY;
    }

    /**
     * (Re)defines the actor's position
     * 
     * @param tileY The Y position to set
     */
    public void setTileY(int tileY) {
        this.tileY = tileY;
    }

    /**
     * Moves the actor in a given direction
     * 
     * @param mDirection The desired direction
     * @return The position to where he moved, or null if he can't move there
     */
    public Vector2D move(int mDirection) {
        int targetX = getTileX();
        int targetY = getTileY();
        switch (mDirection) {
        case ServerMap.EAST:
            targetX++;
            break;
        case ServerMap.WEST:
            targetX--;
            break;
        case ServerMap.NORTH:
            targetY--;
            break;
        case ServerMap.SOUTH:
            targetY++;
            break;
        case ServerMap.NORTHEAST:
            targetX++;
            targetY--;
            break;
        case ServerMap.NORTHWEST:
            targetX--;
            targetY--;
            break;
        case ServerMap.SOUTHEAST:
            targetX++;
            targetY++;
            break;
        case ServerMap.SOUTHWEST:
            targetX--;
            targetY++;
            break;
        }

        // More than one tile movement check
        if (Math.abs(targetX - getTileX()) > 1
                || Math.abs(targetY - getTileY()) > 1)
            return null;

        System.out.println("Trying to move to " + targetX + "," + targetY);

        // Ask the map to move
        Vector2D newLocation =
                map.move(getTileX(), getTileY(), targetX, targetY);
        if (newLocation != null) {
            tileX = newLocation.getX();
            tileY = newLocation.getY();
            return newLocation;
        }

        return null;
    }
}